//给定一个已按照 非递减顺序排列 的整数数组 numbers ，请你从数组中找出两个数满足相加之和等于目标数 target 。 
//
// 函数应该以长度为 2 的整数数组的形式返回这两个数的下标值。numbers 的下标 从 1 开始计数 ，所以答案数组应当满足 1 <= answer[0]
// < answer[1] <= numbers.length 。 
//
// 你可以假设每个输入 只对应唯一的答案 ，而且你 不可以 重复使用相同的元素。 
// 
//
// 示例 1： 
//
// 
//输入：numbers = [2,7,11,15], target = 9
//输出：[1,2]
//解释：2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。
// 
//
// 示例 2： 
//
// 
//输入：numbers = [2,3,4], target = 6
//输出：[1,3]
// 
//
// 示例 3： 
//
// 
//输入：numbers = [-1,0], target = -1
//输出：[1,2]
// 
//
// 
//
// 提示： 
//
// 
// 2 <= numbers.length <= 3 * 104 
// -1000 <= numbers[i] <= 1000 
// numbers 按 非递减顺序 排列 
// -1000 <= target <= 1000 
// 仅存在一个有效答案 
// 
// Related Topics 数组 双指针 二分查找 
// 👍 622 👎 0

package com.cute.leetcode.editor.cn;
public class TwoSumIiInputArrayIsSorted {
    public static void main(String[] args) {
        int[] nums = {1,2,3,4,5,7,8};
        new TwoSumIiInputArrayIsSorted().new Solution().twoSum2(nums, 7);
    }
    //leetcode submit region begin(Prohibit modification and deletion)
    class Solution {
        /**
         * 查找两数之和等于目标值
         * 1.头尾双指针速度飞快（简单题重拳出击）
         * 2.暴力双重遍历也不是不行
         * 3.使用二分法，在双重循环的基础上进行改进，外层遍历不变，内层使用二分法查找target-nums[i]
         */
        public int[] twoSum(int[] numbers, int target) {
            int[] res = new int[2];
            int left = 0;
            int right = numbers.length-1;
            while (left<right){
                if (numbers[left] + numbers[right]>target) right--;
                else if (numbers[left] + numbers[right] <target) left++;
                else {
                    res[0] = left+1;
                    res[1] = right+1;
                    break;
                }
            }
            return res;
        }

        /**
         * 使用二分法进行查找
         */
        public int[] twoSum2(int[] numbers, int target) {
            int len = numbers.length;
            for (int i = 0; i < len-1 ; i++) {
                int index = binarySearch(numbers, i + 1, len - 1, target - numbers[i]);
                if (index != -1) return new int[]{i+1,index+1};
            }
            return null;
        }

        public int binarySearch(int[] nums, int left, int right, int target){
            while (left < right){
                int mid = left + (right-left)/2;
                if (nums[mid]<target){
                    left = mid+1;
                }else right = mid;
            }
            if (nums[left] == target) return left;
            return -1;
        }
    }
//leetcode submit region end(Prohibit modification and deletion)


}